package com.example.fmgidsprototype.webservice;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import org.json.JSONException;
import org.json.JSONObject;

import com.google.android.gms.auth.GoogleAuthException;
import com.google.android.gms.auth.GoogleAuthUtil;
import com.google.android.gms.auth.GooglePlayServicesAvailabilityException;
import com.google.android.gms.auth.UserRecoverableAuthException;

import android.accounts.Account;
import android.accounts.AccountManager;
import android.app.Activity;
import android.content.Intent;
import android.os.AsyncTask;
import android.widget.Toast;

public class n_cst_user_authentication extends AsyncTask<Void, Void, Void> {
	private static final String SCOPE = "oauth2:https://www.googleapis.com/auth/userinfo.profile";
	private static final String TOKEN_URL = "https://www.googleapis.com/oauth2/v1/userinfo?access_token=";
	private static final String NAME_KEY = "name";
	private Activity iuo_activity;
	private String is_email;
	
	public n_cst_user_authentication(Activity activity) {
		this.iuo_activity = activity;
	}
	
	public void of_check_user_account()
	{
		if( n_cst_common.of_get_user_name(iuo_activity).equals("n/a")) 
		{
			
			
			AccountManager lnv_account_manager = AccountManager.get(iuo_activity);
			
			
			Account[] lnv_accounts = lnv_account_manager.getAccountsByType("com.google");
			
				
			if(lnv_accounts.length > 0){
				if(lnv_accounts.length == 1)
				{
					is_email = lnv_accounts[0].name;
		
					this.execute();
				}
				else 
				{
					Intent luo_account_list = new Intent(iuo_activity, AccountList.class);
					luo_account_list.putExtra(AccountList.INTENT_ARGUMENT, lnv_accounts);
					iuo_activity.startActivityForResult(luo_account_list, AccountList.REQUEST_CODE);
				}
			}
			else
			{
				String ls_message = "No Google acccounts found!\r\nPlease create one.";
				Toast lnv_popup = Toast.makeText(iuo_activity.getApplicationContext(), ls_message, Toast.LENGTH_LONG);
				lnv_popup.show();
			}
		}
	}
	
	public void of_set_email(String as_email)
	{
		is_email = as_email;
		
		this.execute();
	}

	@Override
	protected void onPreExecute() {
		// no need for this one	any more, can go out
	}
	
	@Override
	protected Void doInBackground(Void... arg0) {
		try {
			fetchNameFromProfileServer();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
	
	private void fetchNameFromProfileServer() throws IOException, JSONException 
	{
      String ls_token = fetchToken();
      if (ls_token == null) 
      {
        // error has already been handled in fetchToken()
    	  ls_token = fetchToken();
          if (ls_token == null) 
          {
            // error has already been handled in fetchToken()
            return;
          }
      }
      URL lnv_url = new URL(TOKEN_URL + ls_token);
      HttpURLConnection con = (HttpURLConnection) lnv_url.openConnection();
      int li_response_code = con.getResponseCode();
      if (li_response_code == 200) 
      {
        InputStream lnv_input_stream = con.getInputStream();
        String ls_name = getFirstName(readResponse(lnv_input_stream));
        //iuo_activity.show("Hello " + name + "!");
        
        n_cst_common.of_set_user_name(iuo_activity, ls_name);
        
        lnv_input_stream.close();
      }
	}
	
	private String fetchToken() throws IOException {
	      try {
	          return GoogleAuthUtil.getToken(iuo_activity, is_email, SCOPE);
	      } catch (GooglePlayServicesAvailabilityException playEx) {
	          // GooglePlayServices.apk is either old, disabled, or not present.
	          // Show Error
	    	  playEx.printStackTrace();
	      } catch (UserRecoverableAuthException anv_user_recoverable_exception) {
	          // Unable to authenticate, but the user can fix this.
	          // Forward the user to the appropriate activity.
	    	  iuo_activity.startActivityForResult(anv_user_recoverable_exception.getIntent(), 1000);
	    	  anv_user_recoverable_exception.printStackTrace();
	      } catch (GoogleAuthException anv_fatal_exception) {
	          //onError("Unrecoverable error " + fatalException.getMessage(), fatalException);
	    	  anv_fatal_exception.printStackTrace();
	      }
	      return null;
	  }
	/**
     * Reads the response from the input stream and returns it as a string.
     */
    private static String readResponse(InputStream anv_input_stream) throws IOException {
        ByteArrayOutputStream lnv_byte_array_output_stream = new ByteArrayOutputStream();
        byte[] lbt_data = new byte[2048];
        int li_length = 0;
        while ((li_length = anv_input_stream.read(lbt_data, 0, lbt_data.length)) >= 0) {
        	lnv_byte_array_output_stream.write(lbt_data, 0, li_length);
        }
        return new String(lnv_byte_array_output_stream.toByteArray(), "UTF-8");
    }

    /**
     * Parses the response and returns the first name of the user.
     * @throws JSONException if the response is not JSON or if first name does not exist in response
     */
    private String getFirstName(String as_json_response) throws JSONException {
      JSONObject profile = new JSONObject(as_json_response);
      return profile.getString(NAME_KEY);
    }
}
